package com.yhally.seata.storage.tcc;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yhally.seata.storage.dao.StorageDao;
import com.yhally.seata.storage.domain.Storage;
import io.seata.rm.tcc.api.BusinessActionContext;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * @author wangyu
 * @version 1.0
 * @date 2022/5/8 22:11
 */
@Slf4j
@Service
@RequiredArgsConstructor(onConstructor = @_(@Autowired))
public class StorageTccActionImpl implements StorageTccAction {

    private final StorageDao storageDao;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean decrease(BusinessActionContext businessActionContext, Long productId, Integer count) {
        log.info("减少库存：tcc一阶段try开始 [{}]",System.currentTimeMillis());
        Storage storage = storageDao.selectOne(new QueryWrapper<Storage>().eq("product_id", productId));
        storage.setTotal(storage.getTotal()-count);
        storage.setFrozen(storage.getFrozen()+count);
        storageDao.updateById(storage);

        log.info("减少库存：tcc一阶段try成功");
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean commit(BusinessActionContext businessActionContext) {
        // 获取productId和count
        log.info("减少库存：tcc二阶段commit开始，[{}]",System.currentTimeMillis());
        String productId = businessActionContext.getActionContext("productId").toString();
        int count = Integer.parseInt(businessActionContext.getActionContext("count").toString());

        Storage storage = storageDao.selectOne(new QueryWrapper<Storage>().eq("product_id", productId));
        storage.setFrozen(storage.getFrozen()-count);
        storageDao.updateById(storage);

        log.info("减少库存：tcc二阶段commit成功");
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean rollback(BusinessActionContext businessActionContext) {
        String productId = businessActionContext.getActionContext("productId").toString();
        int count = Integer.parseInt(businessActionContext.getActionContext("count").toString());

        Storage storage = storageDao.selectOne(new QueryWrapper<Storage>().eq("product_id", productId));
        storage.setFrozen(storage.getFrozen()-count);
        // 扣减库存失败 要把原先预扣的库存加回来
        storage.setTotal(storage.getTotal()+count);
        storageDao.updateById(storage);

        log.info("减少库存：tcc二阶段回滚成功");
        return true;
    }
}
